/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for DSL Editor PowerToy. A copy of the license can be found in the License.htm file
* at the root of this distribution. If you can not locate the Shared Source License
* for DSL Editor PowerToy, please obtain a copy from: http://www.codeplex.com/dsltreegrideditor/Project/License.aspx.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for DSL Editor PowerToy.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

using VSTrid = Microsoft.VisualStudio.VirtualTreeGrid;

using DslEditorPowerToy.Controls.VirtualTreeGrid.Validation;

namespace DslEditorPowerToy.Controls.VirtualTreeGrid.Branches
{
    /// <summary>
    /// This class displays a placeholder row to allow new rows to be created.
    /// The placeholder row is typically the last row in the branch.
    /// </summary>
    public abstract class NewPlaceholderBranchBase : DefaultNavigationBranchBase, IPlaceholderBranch
    {
        private const int PlaceholderColumnCount = 1;
        private const int PlaceHolderRowCount = 1;

        #region Constructors
        protected NewPlaceholderBranchBase(VirtualTreeGridControl treeControl, Type branchDataItemType)
            : base(treeControl, branchDataItemType)
        {
        }
        #endregion

        #region IBranch Members

        #region Display Data
        /// <summary>
        /// Return the count of visible items in this navigationBranch.
        /// </summary>
        /// <value></value>
        public override int VisibleItemCount
        {
            get
            {
                //Returns number of rows plus placeholder row
                return (this.NonPlaceholderItemCount + PlaceHolderRowCount);
            }
        }
        /// <summary>
        /// Returns the text for the specified cell
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <returns></returns>
        public override string GetText(int row, int column)
        {
            if (true == this.IsNewPlaceholderRow(row))
            {
                if (0 == column)
                    return this.PlaceholderText;
                else
                    return null;
            }
            else
                return base.GetText(row, column);
        }
        /// <summary>
        /// Returns the requested display information
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <param name="requiredData"></param>
        /// <returns></returns>
        public override VSTrid.VirtualTreeDisplayData GetDisplayData(int row, int column,
            VSTrid.VirtualTreeDisplayDataMasks requiredData)
        {
            VSTrid.VirtualTreeDisplayData data = base.GetDisplayData(row, column, requiredData);
            if (0 == column)
            {
                //Override display if new row
                if (true == IsNewPlaceholderRow(row))
                {
                    //Set the text
                    if ((requiredData.Mask & VSTrid.VirtualTreeDisplayMasks.Color) != 0)
                        data.GrayText = true;
                }
            }

            return data;
        }
        /// <summary>
        /// Determines if specified item is expandable
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cellColumnIndex"></param>
        /// <returns></returns>
        public override bool IsExpandable(int row, int column)
        {
            //New row always not expandable
            if (true == IsNewPlaceholderRow(row))
                return false;
            else
                return base.IsExpandable(row, column);
        }
        #endregion

        #region Label Editing
        /// <summary>
        /// Returns the dataItem for initiating label editing
        /// </summary>
        /// <returns></returns>
        public override VSTrid.VirtualTreeLabelEditData BeginLabelEdit(int row, int column,
            VSTrid.VirtualTreeLabelEditActivationStyles activationStyle)
        {
            //Enable editing of placeholder
            if (true == this.IsNewPlaceholderRow(row))
            {
                if (0 != column)
                    return VSTrid.VirtualTreeLabelEditData.Invalid;

                //Clear placeholder text
                return new VSTrid.VirtualTreeLabelEditData(string.Empty, 0);
            }

            return base.BeginLabelEdit(row, column, activationStyle);
        }
        /// <summary>
        /// Determines if edited value is valid
        /// </summary>
        public override VSTrid.LabelEditResult CommitLabelEdit(int row, int column, string newText)
        {
            //Enable editing of placeholder
            if (true == this.IsNewPlaceholderRow(row))
            {
                if (0 == column)
                {
                    int absRowIndex = this.TreeControl.CurrentIndex;

                    //Create a new element and populate it
                    string validationMessage = string.Empty;
                    bool success = this.CreateNewDataItem(row, newText, out validationMessage);
                    if (true == success)
                    {
                        //Raise event
                        base.OnBranchDataItemAdded(row);

                        //Set new item and edit value
                        this.TreeControl.CurrentIndex = absRowIndex;
                        this.TreeControl.InLabelEdit = true;

                        return VSTrid.LabelEditResult.AcceptEdit;
                    }
                    else
                    {
                        if (true == string.IsNullOrEmpty(validationMessage))
                            ValidationHelper.DisplayDefaultValidationError();
                        else
                            ValidationHelper.DisplayError(validationMessage);

                        return VSTrid.LabelEditResult.CancelEdit;
                    }
                }
            }

            return base.CommitLabelEdit(row, column, newText);
        }
        #endregion

        #endregion

        #region IBranchItemData Members
        public override DataItemFlags GetDataItemFlags(int row)
        {
            if (true == IsNewPlaceholderRow(row))
                return (base.GetDataItemFlags(row)
                    & ~DataItemFlags.CanMove
                    & ~DataItemFlags.CanDelete);
            else
                return base.GetDataItemFlags(row);
        }
        public override bool RemoveDataItem(int row)
        {
            //Ensure not deleting placeholder row
            if (true == IsNewPlaceholderRow(row))
                return false;

            return base.RemoveDataItem(row);
        }
        public override bool MoveDataItem(int fromRow, int toRow)
        {
            //Ensure not moving placeholder row
            if ((true == IsNewPlaceholderRow(fromRow))
                || (true == IsNewPlaceholderRow(toRow)))
                return false;

            return base.MoveDataItem(fromRow, toRow);
        }
        #endregion

        #region BranchBase Members
        /// <summary>
        /// Returns number of jagged columns
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public override int GetJaggedColumnCount(int row)
        {
            if (true == IsNewPlaceholderRow(row))
                return PlaceholderColumnCount;
            else
                return base.GetJaggedColumnCount(row);
        }
        #endregion

        #region IPlaceholderBranch Members
        /// <summary>
        /// Gets the number of visible non-placeholder items
        /// </summary>
        public abstract int NonPlaceholderItemCount
        {
            get;
        }
        /// <summary>
        /// Gets the string to display in the placeholder
        /// </summary>
        public abstract string PlaceholderText
        {
            get;
        }
        /// <summary>
        /// Creates a new dataItem item to replace placeholder
        /// </summary>
        /// <param name="insertBeforeRow"></param>
        /// <param name="text"></param>
        public abstract bool CreateNewDataItem(int insertBeforeRow, string primaryText,
            out string validationMessage);
        #endregion

        #region Protected Methods
        /// <summary>
        /// Determines if the specified row columnIndex is for the placeholder
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        protected bool IsNewPlaceholderRow(int row)
        {
            return (row >= this.NonPlaceholderItemCount);
        }
        #endregion
    }
}
